<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>

</body>
<script>
    // 上节中写 type 函数时，用来存放 toString 映射结果的对象
    var class2type = {};

    // 相当于 Object.prototype.toString
    var toString = class2type.toString;

    // 相当于 Object.prototype.hasOwnProperty
    //【知识点】因为javascript没有将hasOwnProperty作为一个敏感词，所以我们很有可能将对象的一个属性命名为hasOwnProperty，
    // 这样一来就无法再使用对象原型的 hasOwnProperty 方法来判断属性是否是来自原型链。
    // 怎么来解决这个问题呢？我们需要使用原型链上真正的 hasOwnProperty 方法：

    var hasOwn = class2type.hasOwnProperty;
    //用来判定是不是原生对象，返回布尔值
    function isPlainObject(obj) {
        var proto, Ctor;

        // 排除掉明显不是obj的以及一些宿主对象如Window
        if (!obj || toString.call(obj) !== "[object Object]") {
            return false;
        }

        /**
         * getPrototypeOf es5 方法，获取 obj 的原型
         * 以 new Object 创建的对象为例的话
         * obj.__proto__ === Object.prototype
         */
        proto = Object.getPrototypeOf(obj); //如果传入字面量对象，此处抓到的是Object原型吗？

        // 没有原型的对象是纯粹的，Object.create(null) 就在这里返回 true
        if (!proto) {
            return true;
        }

        /**
         * 以下判断通过 new Object 方式创建的对象
         * 判断 proto 是否有 constructor 属性，如果有就让 Ctor 的值为 proto.constructor
         * 如果是 Object 函数创建的对象，Ctor 在这里就等于 Object 构造函数
         */
        //按理说，我们应该使用proto，也就是这个对象上的hasOwnProperty方法，但是为了防止这个方法被覆盖，我们直接使用Object上的hasOwnProperty

        //Ctor值，抓取一个对象的构造函数，同时还要求hasOwnProperty不能被覆盖
        Ctor = hasOwn.call(proto, "constructor") && proto.constructor;

        // 在这里判断 Ctor 构造函数是不是 Object 构造函数，用于区分自定义构造函数和 Object 构造函数

        //如果===function说明是Object的包装类型 
        debugger
        return typeof Ctor === "function" && hasOwn.toString.call(Ctor) === hasOwn.toString.call(Object);
    };

    function Student() {
        this.name = 1;
        this.age = 2;
        this.sex = 3;
        this.score = 1;
    }
    var ss = {
        name: "sky"
    }
    console.log(isPlainObject(ss));
</script>

</html>